#include "define.h"
#include "main.h"
#include "display.h"
#include "pieces.h"
#include "music.h"
#include "animation.h"

Menu* menu;
Game* game;
int frame = 0;

extern PIECES pieces;
extern int crt_board[BOARD_ROW][BOARD_COL];
extern int chess_board[BOARD_ROW][BOARD_COL];

int main(){
    //Initializations
    game = init_game();
    game->state = START_MENU;
    menu = menu_init(3, 1385, 420, -100, 160, START_MENU, game->state, game->background);//Start menu first
    
    bool done = false;
    bool redraw = true;
    ALLEGRO_EVENT event;
    play_chess();
    //Game loop
    while(1){
        al_wait_for_event(game->queue, &event);
        switch(event.type)
        {
            case ALLEGRO_EVENT_TIMER:
                frame++;
                if(frame % 60 == 0) frame = 0;
                shadow_update();
                eat_bubble_update();
                checkmate_bubble_update();
                redraw = true;
                break;

            case ALLEGRO_EVENT_DISPLAY_CLOSE:
                done = true;
                break;
            case ALLEGRO_EVENT_KEY_CHAR:
                if(game->state == GAME_END){
                    menu = menu_init(3, 1385, 420, -100, 160, START_MENU, START_MENU, game->background);//Start menu first
                    game->background = al_load_bitmap("res/bg.png");
                    game->state = START_MENU;
                }
                if(event.keyboard.keycode == ALLEGRO_KEY_ESCAPE){
                    if(game->state == GAME_MODE_1){
                        menu = menu_init(3, 750, 300, 0, 150, PAUSE_MENU, game->state, game->background);
                        game->state = PAUSE_MENU;
                        game->background = al_load_bitmap("res/bg2.png");
                    }
                    else if(game->state == START_MENU) done = true;
                    else menu_exit(game);
                    break;
                }
                if(game->state == START_MENU || game->state == PAUSE_MENU)
                    if(menu_update(&event)) menu_jumpto(game);
                if(game->state == GAME_MODE_1) pselect_update(&event);

                
                break;
            case ALLEGRO_EVENT_MOUSE_AXES:
                if(game->state == GAME_MODE_1) pselect_update(&event);
                break;
            case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
                if(game->state == GAME_END){
                    menu = menu_init(3, 1385, 420, -100, 160, START_MENU, START_MENU, game->background);//Start menu first
                    game->background = al_load_bitmap("res/bg.png");
                    game->state = START_MENU;
                }
                if(game->state == GAME_MODE_1) pselect_update(&event);
                break;
        }
        if(done) break;
        if(redraw && al_is_event_queue_empty(game->queue))
        {
            al_clear_to_color(al_map_rgb(0,0,0));
            al_draw_bitmap(game->background, 0, 0, 0);
            if(game->state == START_MENU || game->state == PAUSE_MENU) menu_output(game->select_box);
            else if(game->state == GAME_MODE_1){
                pieces_draw();
                pselect_draw();
                shadow_draw();
                eat_bubble_draw();
                checkmate_bubble_draw();
                win_texts_draw();
            }
            else if(game->state == GAME_END){
                pieces_draw();
                win_texts_draw();
            }
            al_flip_display();
            redraw = false;
        }

    }
    //Cleanup
    clean_game(game);

    return 0;
}

void must_init(bool test, const char *description)
{
    if(test) return;

    printf("couldn't initialize %s\n", description);
    exit(1);
}

Game* init_game(){
    Game* game = malloc(sizeof(Game));
    must_init(al_init(), "allegro");
    must_init(al_install_keyboard(), "keyboard");
    must_init(al_install_mouse(), "mouse");
    game->timer = al_create_timer(1.0 / 60.0);
    must_init(game->timer, "timer");
    game->queue = al_create_event_queue();
    must_init(game->queue, "queue");
    game->disp = Init_display();
    game->trans = Init_trans(game->disp);
    must_init(al_init_font_addon(), "font addon");
    must_init(al_init_ttf_addon(), "ttf addon");
    game->font = al_load_ttf_font("msyh.ttf", 36, 0);
    must_init(al_init_image_addon(), "image");
    game->background = al_load_bitmap("res/bg.png");
    game->select_box = al_load_bitmap("res/select_box.png");
    must_init(al_init_primitives_addon(), "primitives");
    must_init(al_install_audio(), "audio");
    must_init(al_init_acodec_addon(), "audio codecs");
    must_init(al_reserve_samples(16), "reserve samples");
    bgm_init();
    sfx_init();
    al_register_event_source(game->queue, al_get_keyboard_event_source());
    al_register_event_source(game->queue, al_get_display_event_source(game->disp));
    al_register_event_source(game->queue, al_get_timer_event_source(game->timer));
    al_register_event_source(game->queue, al_get_mouse_event_source());
    al_start_timer(game->timer);
    return game;
}

void clean_game(Game *game){
    al_destroy_display(game->disp);
    al_destroy_timer(game->timer);
    al_destroy_event_queue(game->queue);
    al_destroy_font(game->font);
    al_destroy_bitmap(game->background);
    al_destroy_bitmap(game->select_box);
    free(game);
}